#!/usr/bin/wish

### ToDo
### 1) .txt getth linked to font height - potential bug
###    Spacings and margings must be counted too.

################################################################################
### Variables ##################################################################
################################################################################

### Debug variables
## Open default file
set debug001 1
set default_file_name "vsclib013.lib"
set default_file_name "test.lib"

### Cell List hrefs
set cell_list_hrefs ""


################################################################################
### Intarface ##################################################################
################################################################################
wm title . "Liberty Editor"
### Menu
menu .mbar
. config -menu .mbar
.mbar add cascade -label "File" -underline 0  \
                  -menu [menu .mbar.file -tearoff 0]
.mbar add cascade -label "Tools" -underline 0  \
                  -menu [menu .mbar.tools -tearoff 0]
### Menu->File
.mbar.file add command -label "Open" -underline 0 -state disabled -command {}
.mbar.file add separator
.mbar.file add command -label "Exit" -underline 1 -command exit

### Menu->Tools
.mbar.tools add command -label "Cell list" -underline 0 -command {show_cell_list}

### Text area
text .txt -width 80 -height 24 -wrap none -yscrollcommand ".scrolly set" \
          -xscrollcommand ".scrollx set" \
          -setgrid true -relief flat -bd 0 -maxundo 128 -undo true \
          -font "Courier -12" ;# -spacing1 10 -spacing2 10 -spacing3 10

### Scroll bars
scrollbar .scrolly -command ".txt yview" -width 10
scrollbar .scrollx -command ".txt xview" -orient horizontal -width 10
#scrollbar .scrlsty -command ".lst yview" -width 10

### Line numbers area
canvas .lnm -width 40 -height 60 -bg white

### Reduce boxes area
canvas .rbx -width 10 -height 60 -bg white

### Pack interface

pack .scrolly -side right -fill y
pack .scrollx -side bottom -fill x
pack .lnm    -side left  -fill y
pack .rbx    -side left  -fill y
pack .txt -expand yes -fill both

### Cell list window
proc show_cell_list {} {
  if { ![winfo exists .clst] } {
    toplevel .clst
    wm title .clst "Cell list"
    wm resizable .clst 0 0
    listbox .clst.lst -width 24 -height 24 -relief flat -bg white \
             -yscrollcommand ".clst.scrl set"
    scrollbar .clst.scrl -command ".clst.lst yview" -width 10
    frame .clst.bfrm
    button .clst.bfrm.bup -text "Update" -command ".clst.lst update"
    button .clst.bfrm.bex -text "Close" -command "destroy .clst"
    pack .clst.bfrm -side bottom -fill x
    pack .clst.bfrm.bup -side left -fill x
    pack .clst.bfrm.bex -side right -fill x
    pack .clst.scrl -side right -fill y
    pack .clst.lst  -side right -fill both
    
    rename .clst.lst .clst.lst_
    proc .clst.lst { command args } {
      #puts ".lst: $command $args"
      global cell_list_hrefs
      switch $command {
        "update" {
          if { [winfo exists .clst] } {
            .clst.lst_ delete 0  end
            set cell_list_hrefs ""
            set last_line [lindex [split [.txt_ index end-1c ] "."] 0]
            for { set i 1 } { $i <= $last_line } { incr i 1} {
              set line [.txt_ get $i.0 "$i.0 lineend"]
              if { [regexp {^\s*cell\s*\((\w+)\)} $line m m1] } {
                .clst.lst_ insert end $m1
                lappend cell_list_hrefs $i
                #puts $cell_list_hrefs
              }
            } ;# for i
          }
          set result 0
        }
        "selection" {
          if { [lindex $args 0] == "set" } {
            #puts $cell_list_hrefs
            .txt see "[lindex $cell_list_hrefs [lindex $args 1]].0"
          }
          set result [uplevel .clst.lst_ $command $args]
        }
        default {
          set result [uplevel .clst.lst_ $command $args]
        }
      }
      return $result
    }
    bind .clst.lst <Expose> {.clst.lst update}
  } else {
    raise .clst
  }
}

################################################################################
### Event handlers #############################################################
################################################################################

### Text area event handler
rename .txt .txt_
proc .txt {command args} {
    ### getfdl - Returns first displayed line number
    ### getth  - Returns height in chars
  switch $command {
    "getfdl" {
      set last_line [lindex [split [.txt_ index end-1c ] "."] 0]
      set result [expr int ( [ lindex [.txt_ yview] 0 ] * $last_line + 1.5 ) ]
    }
    "update_tag" {
      set last_line [lindex [split [.txt_ index end-1c ] "."] 0]
      set level 0
      for { set i 1 } { $i <= $last_line } { incr i 1} {
        set last_char [lindex [split [.txt_ index "$i.0 lineend"] "." ] 1 ]
        for { set j 0 } { $j <= $last_char } { incr j } {
          set char [.txt_ get $i.$j]
        } ;# for j
      } ;# for i
      set result 0
    }
    "getth" {
      set fsize [ expr -( [lindex [ .txt_ cget -font ] 1 ] ) ]
      set hpix [ winfo height .txt ]
      set result [expr ( $hpix - 6) / ( $fsize + 1 ) ]
    }
    default {
      set result [uplevel .txt_ $command $args]
      if { $command == "yview" ||
           $command == "see" } {
        .lnm redraw
      }
    }
  }        
  return $result
}

### Line numbers area handler
rename .lnm .lnm_
proc .lnm {command args} {
  switch $command {
    "redraw" {
      .lnm addtag ttt all
      .lnm delete ttt
      set first_line [.txt getfdl]
      set lines_count [.txt getth]
      set last_line [expr $first_line + $lines_count]
      set font [.txt_ cget -font]
      for { set i $first_line } { $i <= $last_line } {incr i} {
        if { [set coords [.txt_ bbox "$i.1"]] != ""} {
          set y [lindex $coords 1]
          set item [.lnm create text 2 $y -font $font -text $i -anchor nw]
        }
      }
      set bbx [.lnm bbox $item]
      set width [expr [lindex $bbx 2] - [lindex $bbx 0] + 2]
      .lnm_ configure -width [expr [lindex $bbx 2] - [lindex $bbx 0] + 2]      
      set result 0
    }
    default {
      set result [uplevel .lnm_ $command $args]
    }
  }
  return $result
}
bind .lnm <Expose> {.lnm redraw}

################################################################################
### Open default file for debug ################################################
################################################################################

if { $debug001 == 1 } {
  set IFH [open $default_file_name "r"]
  while { ![eof $IFH] } {
    set line [gets $IFH]
    if { ![eof $IFH] } {
      .txt_ insert end "$line\n"
    }
  }
  close $IFH
  .txt_ edit reset
  #.txt update_tag
  #.lst update
}

### EOF

#puts [.txt_ index "1.0 lineend"]
